{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "9c870dcb-c66d-454d-a3fa-5f9a723bf8af",
   "metadata": {},
   "source": [
    "<center><img src=https://raw.githubusercontent.com/feast-dev/feast/master/docs/assets/feast_logo.png width=400/></center>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "339ab741-ac90-4763-9971-3b274f6a90b4",
   "metadata": {},
   "source": [
    "# Credit Risk Model Serving"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "31d29794-4c33-4bc1-9bb4-e238c59f882d",
   "metadata": {},
   "source": [
    "### Introduction"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d6553fe7-5427-4ecc-b638-615b47acf1a8",
   "metadata": {},
   "source": [
    "Model serving is an exciting part of AI/ML. All of our previous work was building to this phase where we can actually serve loan predictions. \n",
    "\n",
    "So what role does Feast play in model serving? We've already seen that Feast can \"materialize\" data from the training offline store to the serving online store. This comes in handy because many models need contextual features at inference time. \n",
    "\n",
    "With this example, we can imagine a scenario something like this:\n",
    "1. A bank customer submits a loan application on a website. \n",
    "2. The website backend requests features, supplying the customer's ID as input.\n",
    "3. The backend retrieves feature data for the ID in question.\n",
    "4. The backend submits the feature data to the model to obtain a prediction.\n",
    "5. The backend uses the prediction to make a decision.\n",
    "6. The response is recorded and made available to the user.\n",
    "\n",
    "With online requests like this, time and resource usage often matter a lot. Feast facilitates quickly retrieving the correct feature data.\n",
    "\n",
    "In real-life, some of the contextual feature data points could be requested from the user, while others are retrieved from data sources. While outside the scope of this example, Feast does facilitate retrieving request data, and joining it with feature data. (See [Request Source](https://rtd.feast.dev/en/master/#request-source)).\n",
    "\n",
    "In this notebook, we request feature data from the online store for a small batch of users. We then get outcome predictions from our trained model. This notebook is a continuation of the work done in the previous notebooks; it comes as the step after [03_Credit_Risk_Model_Training.ipynb](03_Credit_Risk_Model_Training.ipynb)."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "53818109-c357-435f-8a8b-2a62982fa9a8",
   "metadata": {},
   "source": [
    "### Setup"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "92b5ab1b-186d-4b76-aac7-9b5110f8673e",
   "metadata": {},
   "source": [
    "*The following code assumes that you have read the example README.md file, and that you have setup an environment where the code can be run. Please make sure you have addressed the prerequisite needs.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "378189ed-e967-4b2b-b591-aab980a685b3",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Imports\n",
    "import os\n",
    "import joblib\n",
    "import json\n",
    "import requests\n",
    "import warnings\n",
    "import pandas as pd\n",
    "\n",
    "from feast import FeatureStore"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ea90edb2-16f0-4d40-a280-4e6ea79ea5be",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ingnore warnings\n",
    "warnings.filterwarnings(action=\"ignore\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "55f8ed91-7c13-44f7-a294-b6cacd43f8db",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load the model\n",
    "model = joblib.load(\"rf_model.pkl\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "3093e1b6-66d9-4936-b197-d853631914db",
   "metadata": {},
   "source": [
    "### Query Feast Online Server for Feature Data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2b5bbc4a-e2d3-4b7b-8309-434ff3b3e2cf",
   "metadata": {},
   "source": [
    "Here, we show two different ways to retrieve data from the online feature server. The first is using the Python `requests` library, and the second is using the Feast Python SDK.\n",
    "\n",
    "We can use the Python requests library to request feature data from the online feature server (that we deployed in notebook [02_Deploying_the_Feature_Store.ipynb](02_Deploying_the_Feature_Store.ipynb)). The request takes the form of an HTTP POST command sent to the server endpoint (`url`). We request the data we need by supplying the entity and feature information in the data payload. We also need to specify an `application/json` content type in the request header."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "c6fd4f1a-917b-4a98-9bf6-101b4a074b64",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ID examples\n",
    "ids = [18, 764, 504, 454, 453, 0, 1, 2, 3, 4, 5, 6, 7, 8]\n",
    "\n",
    "# Submit get_online_features request to Feast online store server\n",
    "response = requests.post(\n",
    "    url=\"http://localhost:6566/get-online-features\",\n",
    "    headers = {'Content-Type': 'application/json'},\n",
    "    data=json.dumps({\n",
    "        \"entities\": {\"ID\": ids},\n",
    "        \"features\": [\n",
    "            \"data_a:duration\",\n",
    "            \"data_a:credit_amount\",\n",
    "            \"data_a:installment_commitment\",\n",
    "            \"data_a:checking_status\",\n",
    "            \"data_b:residence_since\",\n",
    "            \"data_b:age\",\n",
    "            \"data_b:existing_credits\",\n",
    "            \"data_b:num_dependents\",\n",
    "            \"data_b:housing\"\n",
    "        ]\n",
    "    })\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8e616a52-c18c-44a9-9e63-3aba071d7e79",
   "metadata": {},
   "source": [
    "The response is returned as JSON, with feature values for each of the IDs."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "cf8948b7-4ed7-4c45-8acf-462331d9e4d2",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'{\"metadata\":{\"feature_names\":[\"ID\",\"checking_status\",\"duration\",\"installment_commitment\",\"credit_amount\",\"residence_since\",\"num_dependents\",\"age\",\"housing\",\"existing_credits\"]},\"results\":[{\"values\":[18,764,504,454,453,0,1,2,3,4,5,6,7,8],\"statuses\":[\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\"],\"event_timestamps\":[\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\",\"1970-01-01T00:00:00Z\"]},{\"values\":[\"0<=X<200\",\"no checking\",\"<0\",\"<0\",\"no checking\",\"<0\",\"0<=X<200\",\"no checking\",\"<0\",\"<0\",\"no checking\",\"no checking\",\"0<=X<200\",\"no checking\"],\"statuses\":[\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",\"PRESENT\",'"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Show first 1000 characters of response\n",
    "response.text[:1000]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c719f702-578a-4f35-b8ff-e41707cda23e",
   "metadata": {},
   "source": [
    "As the response data comes in JSON format, there is a little formatting required to organize the data into a dataframe with one record per row (and features as columns)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "b992063d-8d83-4bf7-8153-f690b0410359",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>checking_status</th>\n",
       "      <th>duration</th>\n",
       "      <th>installment_commitment</th>\n",
       "      <th>credit_amount</th>\n",
       "      <th>residence_since</th>\n",
       "      <th>num_dependents</th>\n",
       "      <th>age</th>\n",
       "      <th>housing</th>\n",
       "      <th>existing_credits</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18</td>\n",
       "      <td>0&lt;=X&lt;200</td>\n",
       "      <td>24.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>12579.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>44.0</td>\n",
       "      <td>for free</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>764</td>\n",
       "      <td>no checking</td>\n",
       "      <td>24.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>2463.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>27.0</td>\n",
       "      <td>own</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>504</td>\n",
       "      <td>&lt;0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1207.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>rent</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    ID checking_status  duration  installment_commitment  credit_amount  \\\n",
       "0   18        0<=X<200      24.0                     4.0        12579.0   \n",
       "1  764     no checking      24.0                     4.0         2463.0   \n",
       "2  504              <0      24.0                     4.0         1207.0   \n",
       "\n",
       "   residence_since  num_dependents   age   housing  existing_credits  \n",
       "0              2.0             1.0  44.0  for free               1.0  \n",
       "1              3.0             1.0  27.0       own               2.0  \n",
       "2              4.0             1.0  24.0      rent               1.0  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Inspect the response\n",
    "resp_data = json.loads(response.text)\n",
    "\n",
    "# Transform JSON into dataframe\n",
    "records = pd.DataFrame(\n",
    "    columns=resp_data[\"metadata\"][\"feature_names\"], \n",
    "    data=[[r[\"values\"][i] for r in resp_data[\"results\"]] for i in range(len(ids))]\n",
    ")\n",
    "records.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6db9b8ac-146e-40d3-b35a-cf4f4b6bbc8a",
   "metadata": {},
   "source": [
    "Now, let's see how we can do the same with the Feast Python SDK. Note that we instantiate our `FeatureStore` object with the configuration that we set up in [02_Deploying_the_Feature_Store.ipynb](02_Deploying_the_Feature_Store.ipynb), by pointing to the `./Feature_Store` directory."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "765dc62b-e1e7-45fe-88b4-cc0235519ff8",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "WARNING:root:_list_feature_views will make breaking changes. Please use _list_batch_feature_views instead. _list_feature_views will behave like _list_all_feature_views in the future.\n",
      "WARNING:root:Cannot use sqlite_vec for vector search\n"
     ]
    }
   ],
   "source": [
    "# Instantiate FeatureStore object\n",
    "store = FeatureStore(repo_path=\"./Feature_Store\")\n",
    "\n",
    "# Retrieve features\n",
    "records = store.get_online_features(\n",
    "    entity_rows=[{\"ID\":v} for v in ids],\n",
    "    features=[\n",
    "        \"data_a:duration\",\n",
    "        \"data_a:credit_amount\",\n",
    "        \"data_a:installment_commitment\",\n",
    "        \"data_a:checking_status\",\n",
    "        \"data_b:residence_since\",\n",
    "        \"data_b:age\",\n",
    "        \"data_b:existing_credits\",\n",
    "        \"data_b:num_dependents\",\n",
    "        \"data_b:housing\"        \n",
    "    ]\n",
    ").to_df()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "1d214e55-df0b-460d-936c-8951f7365a93",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>credit_amount</th>\n",
       "      <th>installment_commitment</th>\n",
       "      <th>checking_status</th>\n",
       "      <th>duration</th>\n",
       "      <th>num_dependents</th>\n",
       "      <th>housing</th>\n",
       "      <th>age</th>\n",
       "      <th>residence_since</th>\n",
       "      <th>existing_credits</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>18</td>\n",
       "      <td>12579.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>0&lt;=X&lt;200</td>\n",
       "      <td>24.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>for free</td>\n",
       "      <td>44.0</td>\n",
       "      <td>2.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>764</td>\n",
       "      <td>2463.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>no checking</td>\n",
       "      <td>24.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>own</td>\n",
       "      <td>27.0</td>\n",
       "      <td>3.0</td>\n",
       "      <td>2.0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>504</td>\n",
       "      <td>1207.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>&lt;0</td>\n",
       "      <td>24.0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>rent</td>\n",
       "      <td>24.0</td>\n",
       "      <td>4.0</td>\n",
       "      <td>1.0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "    ID  credit_amount  installment_commitment checking_status  duration  \\\n",
       "0   18        12579.0                     4.0        0<=X<200      24.0   \n",
       "1  764         2463.0                     4.0     no checking      24.0   \n",
       "2  504         1207.0                     4.0              <0      24.0   \n",
       "\n",
       "   num_dependents   housing   age  residence_since  existing_credits  \n",
       "0             1.0  for free  44.0              2.0               1.0  \n",
       "1             1.0       own  27.0              3.0               2.0  \n",
       "2             1.0      rent  24.0              4.0               1.0  "
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "records.head(3)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd828758-6c57-4f9e-bbda-3983b6579da2",
   "metadata": {},
   "source": [
    "### Get Predictions from the Model"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f446d7ec-0dae-409a-82a2-c0d7016c2001",
   "metadata": {},
   "source": [
    "Now we can request predictions from our trained model. \n",
    "\n",
    "For convenience, we output the predictions along with the implied loan designations. Remember that these are predictions on loan outcomes, given context data from the loan application process. Since we have access to the actual `class` outcomes, we display those as well to see how the model did.|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "70203f7b-f1e5-46ba-8623-f10bf3a5abf8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Get predictions from the model\n",
    "preds = model.predict(records)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "27001dde-8bdb-4de1-8c33-a76f030748e0",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Load labels\n",
    "labels = pd.read_parquet(\"Feature_Store/data/labels.parquet\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ddc958e8-8ff8-49b1-ac10-fc965f3bf21c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>ID</th>\n",
       "      <th>Prediction</th>\n",
       "      <th>Loan_Designation</th>\n",
       "      <th>True_Value</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>18</th>\n",
       "      <td>18</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>bad</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>764</th>\n",
       "      <td>764</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>504</th>\n",
       "      <td>504</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>bad</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>454</th>\n",
       "      <td>454</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>bad</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>453</th>\n",
       "      <td>453</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>bad</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>bad</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>5</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>6</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>7</td>\n",
       "      <td>0.0</td>\n",
       "      <td>bad</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>8</td>\n",
       "      <td>1.0</td>\n",
       "      <td>good</td>\n",
       "      <td>good</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "      ID  Prediction Loan_Designation True_Value\n",
       "18    18         0.0              bad        bad\n",
       "764  764         1.0             good       good\n",
       "504  504         0.0              bad        bad\n",
       "454  454         0.0              bad        bad\n",
       "453  453         1.0             good       good\n",
       "0      0         1.0             good       good\n",
       "1      1         0.0              bad        bad\n",
       "2      2         1.0             good       good\n",
       "3      3         0.0              bad       good\n",
       "4      4         0.0              bad        bad\n",
       "5      5         1.0             good       good\n",
       "6      6         1.0             good       good\n",
       "7      7         0.0              bad       good\n",
       "8      8         1.0             good       good"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Show preds\n",
    "pd.DataFrame({\n",
    "    \"ID\": ids,\n",
    "    \"Prediction\": preds,\n",
    "    \"Loan_Designation\": [\"bad\" if i==0.0 else \"good\" for i in preds],\n",
    "    \"True_Value\": labels.loc[ids, \"class\"]\n",
    "})"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "87cd592a-61fc-4553-b84a-941d1785910d",
   "metadata": {},
   "source": [
    "It's important to remember that the model's predictions are like educated guesses based on learned patterns. The model will get some predictions right, and other wrong. With the example records above, it looks like the model did pretty good! An AI/ML team's task is generally to make the model's predictions as useful as possible in helping the organization make decisions (for example, on loan approvals).\n",
    "\n",
    "In this case, we have a baseline model. While not ready for production, this model has set a low bar by which other models can be measured. Teams can also use a model like this to help with early testing, and with proving out things like pipelines and infrastructure before more sophisticated models are available.\n",
    "\n",
    "We have used Feast to query the feature data in support of model serving. The next notebook, [05_Credit_Risk_Cleanup.ipynb](05_Credit_Risk_Cleanup.ipynb), cleans up resources created in this and previous notebooks."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
